/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <sys/ioctl.h>

int serial_init(int *fcom, char *com, int baudrate)
{
    /**get com num */

    char linuxCom[12] = "/dev/ttyS";
    int comIndex = -1;

    if (strncmp(com, "COM", 3) == 0)
    {
        comIndex = atoi(com + 3) - 1;
        if (comIndex < 9)
            linuxCom[9] = comIndex + '0';
        else if (comIndex < 100)
        {
            linuxCom[9] = comIndex / 10 + '0';
            linuxCom[10] = comIndex % 10 + '0';
        }
        else
        {
            printf("com port error! Usage: COM0 ... COM99\n");
            return -1;
        }
        // printf("\ncomIndex = %d\n", comIndex);
        // printf("com = %s\n", linuxCom);
    }
    else
    {
        printf("com port error! Usage: COM0 ... COM99\n");
        return -1;
    }

    /**get baudrate */
    printf("baudrate:%d \n", baudrate);
    /**open and init com port*/
    *fcom = open(linuxCom, O_RDWR | O_NOCTTY | O_NDELAY);
    if (*fcom == -1)
    {
        printf("[%s] open error! %s!\n",linuxCom, strerror(errno));
        return -1;
    }
    printf("serial open\n");

    struct termios options;
    tcgetattr(*fcom, &options);
    switch (baudrate)
    {
    case 9600:
        cfsetispeed(&options, B9600); // 设置输入波特率为921600
        cfsetospeed(&options, B9600); // 设置输出波特率为921600
        break;
    case 115200:
        cfsetispeed(&options, B115200); // 设置输入波特率为921600
        cfsetospeed(&options, B115200); // 设置输出波特率为921600
        break;
    case 256000:
        cfsetispeed(&options, B256000); // 设置输入波特率为921600
        cfsetospeed(&options, B256000); // 设置输出波特率为921600
        break;
    case 921600:
        cfsetispeed(&options, B921600); // 设置输入波特率为921600
        cfsetospeed(&options, B921600); // 设置输出波特率为921600
        break;
    case 2000000:
        cfsetispeed(&options, B2000000); // 设置输入波特率为2000000
        cfsetospeed(&options, B2000000); // 设置输入波特率为2000000
    default:

        cfsetispeed(&options, B921600); // 设置输入波特率为921600
        cfsetospeed(&options, B921600); // 设置输出波特率为921600
        break;
    }
    options.c_cflag |= (CLOCAL | CREAD);                // 忽略调制解调器控制线，启用接收器
    options.c_cflag |= PARENB;                          // 允许校验位.当设置为1时，表示启用校验位；清除该标志则禁用校验位‌
    options.c_cflag &= ~PARODD;                          // 允许奇校验。当设置为1时，表示使用奇校验；当清除该标志时，表示使用偶校验‌
    options.c_cflag &= ~CSTOPB;                         // 1位停止位
    options.c_cflag &= ~CSIZE;                          // 清除数据位设置
    options.c_cflag |= CS8;                             // 设置数据位为8位
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 非规范模式，禁止
    // options.c_lflag = 0;
    options.c_iflag &= ~IGNBRK;
    // options.c_oflag = 0;
    options.c_oflag &= ~OPOST;                          // 原始输出
    options.c_cc[VTIME] = 1;                            // 设置超时1
    options.c_cc[VMIN] = 1;                             // 设置最小字符为1
    tcsetattr(*fcom, TCSANOW, &options);

    printf("serial init done\n");
    return 0;
}
int serial_set_rts(int fcom, int level)
{
    int status;
    ioctl(fcom, TIOCMGET, &status);
    if (level != 1)
    {
        status |= TIOCM_RTS;
    }
    else
    {
        status &= ~TIOCM_RTS;
    }
    ioctl(fcom, TIOCMSET, &status);
    return 0;
}
int serial_clear_buffer(int fcom)
{
    tcflush(fcom, TCIFLUSH);
    tcflush(fcom, TCIOFLUSH);
    return 0;
}
